//==================================================
// NABTON Client: nbScale.ino
// 2015-01-21
// Version 0.1
//==================================================

//==================================================
// Configuration
//==================================================
  #define SIDN  2
  #define SID1 51
  #define SID2 52
  // Big display
  int   zero_level  = 1290;
  float refKg       = 86.7;
  int   refValue    = 3030; 
  float noice_level = 0.1;
  // Small display
  //int   zero_level  = 725;
  //float refKg       = 86.7;
  //int   refValue    = 2026; 
  //float noice_level = 0.2;
  #define N_FILTER 5
//==================================================

int g_sid;
float factor;
float oldTs,newTs;
int value = HIGH;
int nvalue = 0;
int count = 0;
float oldw[10];
float sum,ftemp,weight = 0.0;
int ready = 0;
int sid[10];
 
#define PIN_LED_OK    4
#define PIN_INTERRUPT 2
#define PIN_SIGNAL   10
#define PIN_LED_SID1  7
#define PIN_LED_SID2  8
#define PIN_BUTTON    3
#define PIN_SID_OK    5

#define NABTON_DATA 1
#define NABTON_DATA_ACK 2

//=================================================
void sendNDS(int sid, float data)
//=================================================
{
  //Serial.print(":"); //start
  Serial.print(NABTON_DATA);
  Serial.print(" "); 
  Serial.print(sid);
  Serial.print(" "); 
  Serial.print(data);
  Serial.print(";"); // End
  Serial.flush();
}
//=================================================
void blinkLed(int nn)
//=================================================
{
  digitalWrite(PIN_LED_OK,LOW);
  for(int i=0;i<nn;i++)
  { 
     digitalWrite(PIN_LED_OK,HIGH);
     delay(100);
     digitalWrite(PIN_LED_OK,LOW);
     delay(100);
  }  
}
//=================================================
void recACK()
//=================================================
{
  int nx = Serial.available();
  if (nx > 0) 
  {
        blinkLed(1);
  }
}
//=================================================
void stamp()
//=================================================
{
  int i;
  float gtemp;
  value = digitalRead(PIN_SIGNAL);
  if(value == LOW)
  {
    count++;
  }
  if(count > 0 && value == HIGH)
  {
     nvalue++;
     for(i=N_FILTER;i>0;i--)oldw[i] = oldw[i-1];
     oldw[0]=(count-zero_level)*factor;
     //gtemp=(count-zero_level)*factor;
     ftemp = 0.0;
     sum = 0.0;
     for(i=0;i<N_FILTER;i++)
     {
       ftemp = ftemp + (oldw[i] - oldw[i+1])*(oldw[i] - oldw[i+1]);
     }
     for(i=0;i<=N_FILTER;i++)
     {
       sum = sum + oldw[i];
     }
     sum = sum/(N_FILTER+1);
     if(ftemp < noice_level && sum > 10.0 && sum < 150.)
     {
       weight = sum;
       sum = 0.0;
     }

     /*Serial.print(count);
     Serial.print("  ");
     Serial.print(noice_level);
     Serial.print("  SID=");
     Serial.print(g_sid);
     Serial.print("  ");
     Serial.print(ftemp);
     Serial.print("  ");
     Serial.println(sum);*/
     count = 0;
  }
}
//=================================================
void sidSelect() 
//=================================================
{
  blinkLed(2);
  digitalWrite(PIN_LED_SID1,HIGH); 
  digitalWrite(PIN_LED_SID2,LOW); 
  g_sid = 1;
  while(digitalRead(PIN_SID_OK) == HIGH)
  {
     int res = digitalRead(PIN_BUTTON);
     if(res == LOW) 
     {
       if(g_sid == 1)
       {
         digitalWrite(PIN_LED_SID2,HIGH); 
         digitalWrite(PIN_LED_SID1,LOW); 
         g_sid = 2;
       }
       else if(g_sid == 2) 
       {
         digitalWrite(PIN_LED_SID1,HIGH); 
         digitalWrite(PIN_LED_SID2,LOW); 
         g_sid = 1;
       }
       delay(200);
     }
  }
  blinkLed(5);
}
//=================================================
void setup() 
//=================================================
{
  int i;
  
  sid[0] = SIDN;
  sid[1] = SID1;
  sid[2] = SID2;
  
  Serial.begin(9600);

  pinMode(PIN_SIGNAL,     INPUT);
  pinMode(PIN_LED_OK,     OUTPUT);
  pinMode(PIN_INTERRUPT,  OUTPUT);
  pinMode(PIN_LED_SID1,   OUTPUT);
  pinMode(PIN_LED_SID2,   OUTPUT);
  pinMode(PIN_BUTTON,     INPUT);
  pinMode(PIN_SID_OK,     INPUT);

  digitalWrite(PIN_LED_OK,LOW);
  digitalWrite(PIN_LED_SID1,LOW);
  digitalWrite(PIN_LED_SID2,LOW);
  
  attachInterrupt(0, stamp, FALLING);
  for(i=N_FILTER;i>0;i--)oldw[i] =0.;  
  factor = refKg/(refValue-zero_level); 

  sidSelect();
    // Start interrupt tone
  tone(PIN_INTERRUPT, 32767);
 
}


//=================================================
void loop()
//=================================================
{
  if(weight > 5.0)
  {
       //Serial.print("Your weight is (kg): ");
       //Serial.print(ftemp);
       //Serial.print("  ");
       int s = sid[g_sid];
       sendNDS(s,weight);
       //Serial.println(weight);
       digitalWrite(PIN_LED_OK,HIGH);
       //detachInterrupt(0);
       noTone(PIN_INTERRUPT);
       delay(20000);
       digitalWrite(PIN_LED_OK,LOW);
       sidSelect(); 
       weight = 0.0;
       nvalue = 0;
       //Serial.println("Ready for new measurement");   
       //attachInterrupt(0, stamp, FALLING); 
       tone(PIN_INTERRUPT, 32767);
  }
  

}
